<?php

class yandexDirect {
    private $auth = 0;
    private $std_headers = "";
    private $komis = 0;
    
    public function __construct() {
        $this->std_headers = "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: ru,en-us;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive";
        $this->komis = 0;
        $this->main();        
    }
    
    private function main() {
        $result = '';
        if (!isset($_SESSION['AUTH'])) {
            if ($this->authorize('directest', 'Cr4sh&Burn')) {
                $this->auth = 1;
                $_SESSION['AUTH'] = 1;
            } else {
                //$this->view('error');
                die('AUTH ERROR');
            }
        }
        if (array_key_exists('forecast', $_GET)) {
            $phrases = $_GET['phrases'];
            $result = $this->parseForecastPage($this->getForecastByWords($phrases));
            echo($result);
        } else {
            $this->view('default');
        }
        
    }

    private function getForecastByWords($phrases) {
        $words = preg_split("/[\r\n\s]+/i", $phrases);
        $count_words = count($words);
        $phrases = urlencode($phrases);
        /*
        suggest_request_count_forecast= общее количество слов
        new_phrases= сами слова
        */
        $post_body = "cmd=calcForecast&phrases=&geo=0&new_phrases=$phrases&suggest_request_count_forecast=$count_words&suggest_nonempty_answers_forecast=0&suggest_clear_count_forecast=0&suggest_add_one_phrase_count_forecast=0&suggest_add_all_count_forecast=0&suggest_added_phrases_count_forecast=0&text_rubrics=&ChoosedCategories=&UncheckedCategories=";
        $post_query = "POST /registered/main.pl HTTP/1.1
Host: direct.yandex.ru
{$this->std_headers}
Referer: https://direct.yandex.ru/registered/main.pl?cmd=ForecastByWords
Pragma: no-cache
Cache-Control: no-cache
{$_SESSION['COOKIE']}Content-Type: application/x-www-form-urlencoded
Content-Length: ".strlen($post_body)."\r\n\r\n$post_body\r\n\r\n";
        return $this->httpQuery($post_query, 'ssl', 'direct.yandex.ru');
    }
    
    public function authorize($login, $password) {
        $login = urlencode($login);
        $password = urlencode($password);
        
        $get_query = "GET /passport?mode=passport HTTP/1.1\r\nHost: passport.yandex.ru\r\n{$this->std_headers}\r\n\r\n";
        $this->httpQuery($get_query, 'ssl', 'passport.yandex.ru');
        
        $post_body = "timestamp=1250863070037&login=$login&passwd=$password&twoweeks=yes&In=%C2%EE%E9%F2%E8";
        $post_query = "POST /passport?mode=auth HTTP/1.1
Host: passport.yandex.ru
{$this->std_headers}
Referer: https://passport.yandex.ru/passport?mode=passport
{$_SESSION['COOKIE']}Content-Type: application/x-www-form-urlencoded
Content-Length: ".strlen($post_body)."\r\n\r\n$post_body\r\n\r\n";
        $this->httpQuery($post_query, 'ssl', 'passport.yandex.ru');
        
        return 1;
    }
    
    private function httpQuery($query, $scheme, $host) {
        if (strtolower($scheme) == 'ssl') {
            if ( !($sock = fsockopen("ssl://$host", 443, $errno, $errstr, 30)) ) {
                die("Error: $errstr ($errno)");
            }
        } else {
            if ( !($sock = fsockopen($host, 80, $errno, $errstr, 30)) ) {
                die("Error: $errstr ($errno)");
            }
        }
        $response = '';
        $gzip_body_mark = 0;
        $http_body_mark = 0;
        $gzip_encoding = 0;
        $http_body = '';
        $gzip_body = '';
        $redirect = 0;
        $response_line= '';
        $url_info = '';
        $redirect_query = '';
        $skip_next_line = 0;
        //$sock_open = 1;
        $log = fopen("log", 'a');
        fwrite($log, date("H:i:s")." ".$query);
        fwrite($log, "--------------------------------------------------------------------\n");
        fwrite($sock, $query, strlen($query));
        while ( $response_line = fgets($sock) ) {
            if ($skip_next_line) { $skip_next_line = 0; continue; }
            if ( preg_match("/^Set-Cookie\s*\:\s*(.*)/i", $response_line, $matches) ) {
                $_SESSION['COOKIE'] .= 'Cookie: '.trim($matches[1])."\r\n";
                $cookie = $this->createCookieArray($matches[1]);
                setcookie($cookie['name'], $cookie['value'], time()+1000, $cookie['path'], $cookie['domain']);
            } elseif ( preg_match("/^Content-Encoding\s*\:\s*gzip/i", $response_line, $matches) ) {
                $gzip_encoding = 1;
            } elseif ( preg_match("/^Location\s*\:\s*(.*)/i", $response_line, $matches) ) {
                $matches[1] = trim($matches[1]);
                $url_info['scheme'] = preg_replace("/^(.*)?\:.*/i", "\$1", $matches[1]);
                $url_info['host'] = preg_replace("/.*?\:\/\/([^\/]+)?\/*.*/i", "\$1", $matches[1]);
                $url_info['path'] = preg_replace("/.*?\:\/\/[^\/]+?(\/.*)/i", "\$1", $matches[1]);
                $redirect_query = "GET {$url_info['path']} HTTP/1.1
Host: {$url_info['host']}
{$this->std_headers}
Referer: https://passport.yandex.ru/passport?mode=passport
{$_SESSION['COOKIE']}Content-Type: application/x-www-form-urlencoded\r\n\r\n";
                $redirect = 1;
                $response_line = '';
                break;
            } elseif ( preg_match("/^\x1f\x8b/i", $response_line, $matches) ) {
                //echo("<pre>$response_line</pre><br>\n");
                //echo("BEGIN HTTP BODY $http_body_mark<br>");
                if ($http_body_mark) {
                    if (preg_match("/^\x1f\x8b.{8}$/i", trim($response_line), $matches)) {
                        $skip_next_line = 1;
                        //echo("SKIP<br>");
                        $response_line = '';
                    } else {
                        $response_line = substr($response_line, 10);
                    }
                    $gzip_body_mark = 1;
                }
            } elseif ( preg_match("/^\r\n$/i", $response_line, $matches) ) {
                $response_line = '';
                $http_body_mark = 1;
            } elseif ( preg_match("/^\x30$/i", $response_line, $matches) ) {
                $response_line = '';
                break;
            }
            if ($http_body_mark) {
                if ($gzip_body_mark) {
                    $gzip_body .= $response_line;
                } else {
                    $http_body .= $response_line;
                }
            } else {
                fwrite($log, date("H:i:s")." ".$response_line);
            }
            $response_line = '';
        }
        
        if ($gzip_body_mark) {
            if ( !($response = gzinflate($gzip_body)) ) {
                $errlog = fopen('errlog', 'a');
                fwrite($errlog, $gzip_body);
                fclose($errlog);
            }
            fwrite($log, date("H:i:s")." ".$response);
        } else {
            $response = $http_body;
            fwrite($log, date("H:i:s")." ".$http_body);
        }
        fclose($log);
        fclose($sock);
        if ($redirect) {
            $response = '';
            if (strtolower($url_info['scheme']) == 'https') {
                $this->httpQuery($redirect_query, 'ssl', $url_info['host']);
            } else {
                $this->httpQuery($redirect_query, 'http', $url_info['host']);
            }
        }
        return $response;
    }
    
    private function createCookieArray($line) {
        $cookie_parms = explode(";", $line);
        $result = array();
        $i = 0;
        foreach ($cookie_parms as $cookie) {
            list($key, $val) = explode("=", $cookie, 2);
            if ($i == 0) {
                $result['name'] = trim($key);
                $result['value'] = trim($val);
            } else {
                $result[trim($key)] = trim($val);
            }
            $i++;
            
        }
        return $result;
    }
    private function parseForecastPage(&$html_page) {
        $data = array(0 => array(
                        'phrase' => '',
                        'shows' => 0,
                        'clicks' => 0,
                        'fp_clicks' => 0,
                        'p_clicks' => 0,
                        'ctr' => 0,
                        'fp_ctr' => 0,
                        'p_ctr' => 0,
                        'min' => 0,
                        'max' => 0,
                        'pmin' => 0,
                        'sum' => 0,
                        'fp_sum' => 0,
                        'p_sum' => 0,
                        'pos' => 0,
                        'category_name' => ''
                        )
                     );
        $html_out = '';
        $lines = preg_split("/[\r\n]+/i", $html_page);
        $start = 0;
        $phrase_id = 0;
        $ph_start = 0;
        for ($i = 0; $i < count($lines); $i++) {
            if ( preg_match("/var phrases \= new Array \(/i", $lines[$i]) ) {
                $start = 1;
            }
            if ($start) {
                if ( preg_match("/\}[\s\t]*\)[\s\t]*\;/i", $lines[$i]) ) {
                    $start = 0;
                    break;
                }
                if ( preg_match("/phrase\s*\:\s*\'(.*?)\'/i", $lines[$i], $matches) ) {
                    $ph_start = 1;
                    $data[$phrase_id]['phrase'] = $matches[1];
                } elseif ( preg_match("/\}/i", $lines[$i], $matches) ) {
                    $ph_start = 0;
                    $phrase_id++;
                }
                if ($ph_start) {
                    if ( preg_match("/shows:(.*),\s*clicks:(.*?),\s*fp_clicks:(.*?),\s*p_clicks:(.*?),\s*ctr:(.*?),\s*fp_ctr:(.*?),\s*p_ctr:(.*?),\s*min:(.*),\s*max:(.*?),\s*pmin:(.*?),\s*sum:(.*?),\s*fp_sum:(.*?),\s*p_sum:(.*?),\s*pos:(.*)/i", $lines[$i], $matches) ) {
                        $data[$phrase_id]['shows'] = trim($matches[1]);                 $data[$phrase_id]['clicks'] = trim($matches[2]);
                        $data[$phrase_id]['fp_clicks'] = trim($matches[3]);             $data[$phrase_id]['p_clicks'] = trim($matches[4]);
                        $data[$phrase_id]['ctr'] = round(trim($matches[5]), 2);         $data[$phrase_id]['fp_ctr'] = round(trim($matches[6]), 2);
                        $data[$phrase_id]['p_ctr'] = round(trim($matches[7]), 2);       $data[$phrase_id]['min'] = round(trim($matches[8]), 2) + $this->komis;
                        $data[$phrase_id]['max'] = round(trim($matches[9]), 2) + $this->komis;         $data[$phrase_id]['pmin'] = round(trim($matches[10]), 2) + $this->komis;
                        $data[$phrase_id]['sum'] = round(trim($matches[11]), 2) + $this->komis;        $data[$phrase_id]['fp_sum'] = round(trim($matches[12]), 2) + $this->komis;
                        $data[$phrase_id]['p_sum'] = round(trim($matches[13]), 2) + $this->komis;      $data[$phrase_id]['pos'] = round(trim($matches[14]), 2);
                    } elseif ( preg_match("/category_name\:\s*\'(.*?)\'/i", $lines[$i], $matches) ) {
                        $data[$phrase_id]['category_name'] = preg_replace("/\\\/i", "", trim($matches[1]));
                        if (!empty($data[$phrase_id]['category_name'])) {
                            $data[$phrase_id]['phrase'] = $data[$phrase_id]['category_name'];
                        }
                    }
                }
            }
        }
        $html_out .= '<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Оценка месячного бюджета рекламной кампании</title>
</head><body><table border="0" cellspacing="0" cellpadding="12">
    <tr ><td>
        Слово
      </td>
      <td>
        Позиция
      </td>
      <td nowrap="nowrap">
        Прогноз средней<br/> цены клика,&nbsp;у.е.
      </td>
      <td>
        Прогноз<br/>CTR,%
      </td>
      <td>
        Прогноз<br/>показов
      </td>
       <td>
        Прогноз<br/><nobr>бюджета,&nbsp;у.е.*</nobr>
      </td>
    </tr>';
        $shows_sum = 0; $sum = 0;
        for ($phrase_id = 0; $phrase_id < count($data); $phrase_id++) {
            $shows_sum += $data[$phrase_id]['shows'];
            $sum += $data[$phrase_id]['sum'];
            $html_out .= "
<tr>
<td>
    {$data[$phrase_id]['phrase']}
</td>
<td>
спецразмещение<br>
1-ое местo<br>
гарантированные показы
</td>
<td nowrap=\"nowrap\">
    {$data[$phrase_id]['pmin']}<br>
    {$data[$phrase_id]['max']}<br>
    {$data[$phrase_id]['min']}
</td>
<td>
    {$data[$phrase_id]['p_ctr']}<br>
    {$data[$phrase_id]['fp_ctr']}<br>
    {$data[$phrase_id]['ctr']}
</td>
<td>
    {$data[$phrase_id]['shows']}
</td>
<td>
    {$data[$phrase_id]['p_sum']}<br>
    {$data[$phrase_id]['fp_sum']}<br>
    {$data[$phrase_id]['sum']}
</td>
</tr>\n";
        }
        $html_out .= "<tr>
      <td>&nbsp;</td>
      <td>
        <b>Итого:</b><br />
        <sup>*</sup> 1 у.е. = 30 руб.                                         
      </td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>
        $shows_sum
      </td>
       <td nowrap=\"nowrap\"><br/><b>$sum</b></td>
    </tr>
  </table></body></html>";
        return $html_out;
    }
    private function view($page_name) {
        include_once('./templates/'.strtolower($page_name).'.html');
    }
}
?>
